package org.cglib.example;


import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class CglibProxyFactory implements MethodInterceptor {

    //返回一个代理对象:  是 target 对象的代理对象
    public Object getProxyInstance(Class<?> clazz) {
        //1. 创建一个工具类
        Enhancer enhancer = new Enhancer();
        //2. 设置父类
        enhancer.setSuperclass(clazz);
        //3. 设置回调函数
        enhancer.setCallback(this);
        //4. 创建子类对象，即代理对象
        return enhancer.create(); //在create的时候,框架创建了Teacher的实例

    }

    /**
     * All generated proxied methods call this method instead of the original method. The original method
     * may either be invoked by normal reflection using the Method object, or by using the MethodProxy (faster).
     *
     * @param object–      "this", the enhanced object 就是代理对象(原Teacher的子类),通过hashCode可以判定
     * @param method–      intercepted Method 被拦截的方法,原始类中方法 teach 类型为 java.lang.reflect.Method
     * @param args         – argument array; primitive types are wrapped
     * @param methodProxy– used to invoke super (non-intercepted method); may be called as many times as needed
     *                     代理方法,net.sf.cglib.proxy.MethodProxy
     * @return any value compatible with the signature of the proxied method. Method returning void will ignore this value.
     * @throws Throwable
     */
    //重写  intercept 方法,会调用目标对象的方法
    @Override
    public Object intercept(Object object, Method method, Object[] args,
                            MethodProxy methodProxy) throws Throwable {
        System.out.println();
//        System.out.println("intercept方法中obj的hashCode="+System.identityHashCode(object));
//        System.out.println("intercept方法中method的hashCode="+System.identityHashCode(method.getClass()));
//        System.out.println("intercept方法中proxy的hashCode="+System.identityHashCode(methodProxy));

//        AppCgLigProxyTest.printClassInfo(object.getClass());
//        System.out.println();
//        AppCgLigProxyTest.printClassInfo(method.getClass());
//        System.out.println();
//        AppCgLigProxyTest.printClassInfo(methodProxy.getClass());
//        System.out.println();

//        System.out.println(method.);


        System.out.println(methodProxy.getSuperName());
        System.out.println(methodProxy.getSignature());


        System.out.println("Cglib代理模式---开始");

//  这里的target是原来通过构造器,传递进来的原始Teacher对象
//        Teacher target=new Teacher();
// 		Object returnVal = method.invoke(new Teacher(), args);//正确,调用传递的对象
//        Object returnVal = method.invoke(object, args); // 错误 StackOverflowError


//        Object returnVal = methodProxy.invoke(new Teacher(), args);//成功,调用传递的对象
//        Object returnVal = methodProxy.invoke(object, args); // 错误 StackOverflowError

        Object returnVal = methodProxy.invokeSuper(object,args); // 成功
//        Object returnVal = methodProxy.invokeSuper(new Teacher(), args); //错误
        // ClassCastException: org.cglib.example.Teacher cannot be cast to org.cglib.example.Teacher$$EnhancerByCGLIB$$c035fe31

        System.out.println("Cglib代理模式--- 提交");
        return returnVal;
    }

}
